package org.pay.utils;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

/**
 * Author: yuzzha
 * Date: 2021/12/27 18:35
 * Description:
 * Remark:
 */
public class AES256Utils {

    /**
     * 8      * 密鑰, 256位32個字節
     * 9
     */
    public static final String DEFAULT_SECRET_KEY = "uBdUx82vPHkDKb284d7NkjFoNcKWBuka";

    private static final String AES = "AES";

    /**
     * 初始向量IV, 初始向量IV的長度規定爲128位16個字節, 初始向量的來源爲隨機生成.
     */
    private static final byte[] KEY_VI = "c558Gq0YQK2QUlMc".getBytes();

    /**
     * 加密解密算法/加密模式/填充方式
     */
   // private static final String CIPHER_ALGORITHM = "AES/CBC/PKCS5Padding";
   private static final String CIPHER_ALGORITHM = "AES/CBC/PKCS7Padding";
    private static final String De_CIPHER_ALGORITHM = "AES/CBC/NoPadding";
    //AES/CBC/NoPadding
    //

    static String key = "001d7aca9d3b132846b3895d93dbf627eb11ae186dcc2e90badf2b7e935f57d2";
    static  String iv = "ee91ee13bfd1f3b4abab0061091d500f";

    //             key = 001d7aca9d3b132846b3895d93dbf627eb11ae186dcc2e90badf2b7e935f57d2
    //              iv = ee91ee13bfd1f3b4abab0061091d500f
    // 請求加密前：
    static String blank = "{\n" +
            " \"BuyerID\" : \"318212144952789694\" ,\n" +
            " \"TxType\" : \"22\" ,\n" +
            " \"BillNumber\" : \"6000000316100\" ,\n" +
            " \"Amount\" : 100 ,\n" +
            " \"LocalDate\" : \"20211206\" ,\n" +
            " \"LocalTime\" : \"161004\" ,\n" +
            " \"Detail\" : \"商品 x1,商品 x2,商品 x3\" ,\n" +
            "}";
    static String b="{\"TxType\":\"23\",\"BillNumber\":\"60000003214305\",\"OrderNumber\":\"600000031639662185\",\"LocalDate\":\"20211216\"\n" +
            ",\"LocalTime\":\"214306\"}";

    //JRH00TcJZFRXCUJbs9Egb82RGoCL/CbMMraUX3sfeA9+PzoTw11OkN053G4gSFtzWXIjpU8J5t32Bp
    //QeWNrL2ZvpIvsdYmlu3WUgcqUJTwsITd7ISI6PlxAQaG5xXtnpWqZyJp3yJeOo++OQ5I3YPNOK+PrLFhfL+
    //WVJNThJz68L3CNY3m16Sek13NEUFYuPP/q0bjQCILjPU2YNU9tbQ5vw3bS1DHSCgXs3fzAviBk=

    //DqHLAR5Wf95drsbyw3rLOlg84SVOJgTYl3fn4GHSJSG985xMrYkbJCfBPXBnxqVejpnVsR7ogZSsP0u
    //ugiNffoZN4U/ZeMRYV2e2cYbAFynhF9vhEusda9Lqrrl1gRdEeXHDKYTdh/F1QPpGBBBkLiP7TeiaFf34VBf
    //RpBxlDTU=

    static String en="DqHLAR5Wf95drsbyw3rLOlg84SVOJgTYl3fn4GHSJSG985xMrYkbJCfBPXBnxqVejpnVsR7ogZSsP0u\n" +
            "ugiNffoZN4U/ZeMRYV2e2cYbAFynhF9vhEusda9Lqrrl1gRdEeXHDKYTdh/F1QPpGBBBkLiP7TeiaFf34VBf\n" +
            "RpBxlDTU=";




    private static final String charset = "UTF-8";

    public static void mains(String[] args) {


        try {

            //明文
            byte[] contentBytes = b.getBytes(charset);
            byte[] keyBytes = HexString2Bytes(key);
            System.out.println("AES KEY size:" + keyBytes.length);
            byte[] initParam = HexString2Bytes(iv);
            System.out.println("AES IV size:" + initParam.length);
            byte[] encrypt = encode(keyBytes, initParam, contentBytes);
            String encryptBase = Base64Utils.encodeStr(encrypt);
            System.out.println(encryptBase);

            System.out.println("---------------------------> ");

            String tes = "JRH00TcJZFRXCUJbs9Egb82RGoCL/CbMMraUX3sfeA9+PzoTw11OkN053G4gSFtzWXIjpU8J5t32BpQeWNrL2ZvpIvsdYmlu3WUgcqUJTwsITd7ISI6PlxAQaG5xXtnpWqZyJp3yJeOo++OQ5I3YPNOK+PrLFhfL+WVJNThJz68L3CNY3m16Sek13NEUFYuPP/q0bjQCILjPU2YNU9tbQ5vw3bS1DHSCgXs3fzAviBk=";
            //JRH00TcJZFRXCUJbs9Egb82RGoCL/CbMMraUX3sfeA9+PzoTw11OkN053G4gSFtzWXIjpU8J5t32BpQeWNrL2ZvpIvsdYmlu3WUgcqUJTwsITd7ISI6PlxAQaG5xXtnpnvzfCB8ZukJCHKKlRtPfvOi3SgQoPrtHGd5MvGYSA+VQlAdYGstMBMjcqSeIiuL/b3/K5rUfs6aHuVAXA0sOkC8gUbLyoEjytScHmCjKzCs=

            byte[] decode = decode(keyBytes, initParam,encrypt);
            System.out.println("---------------------------> decrypt :" + new String(decode));
          /*  byte[] decodes = decode(keyBytes, initParam,en.getBytes());
            System.out.println("---------------------------> decodes :" + new String(decodes));*/
            byte[] decode64 = decode(keyBytes, initParam,Base64Utils.decode(en));
            System.out.println("---------------------------> decode64 :" + new String(decode64));
           String ree= "JRH00TcJZFRXCUJbs9Egb82RGoCL/CbMMraUX3sfeA9+PzoTw11OkN053G4gSFtzWXIjpU8J5t32Bp" +
                    "QeWNrL2ZvpIvsdYmlu3WUgcqUJTwsITd7ISI6PlxAQaG5xXtnpWqZyJp3yJeOo++OQ5I3YPNOK+PrLFhfL+" +
                    "WVJNThJz68L3CNY3m16Sek13NEUFYuPP/q0bjQCILjPU2YNU9tbQ5vw3bS1DHSCgXs3fzAviBk=";
            byte[] Endecode64 = decode(keyBytes, initParam,Base64Utils.decode(ree));
            System.out.println("---------------------------> Endecode64 :" + new String(Endecode64));
        } catch (Exception e) {
            System.out.println("---------------------------> doReqPayTask e :" + e.toString());
            throw new RuntimeException(e);
        }
    }

    /**
     * AES加密
     */
    public static byte[] encode(byte[] key, byte[] iv, byte[] content) {
        try {
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

            cipher.init(Cipher.ENCRYPT_MODE,  new SecretKeySpec(key, AES), new IvParameterSpec(iv)); // 初始化爲加密模式 return cipher.doFinal(dataToEncrypt.getBytes("UTF-8")); // 執行加密

  /*          javax.crypto.SecretKey secretKey = new javax.crypto.spec.SecretKeySpec(key, AES);
            javax.crypto.Cipher cipher = javax.crypto.Cipher.getInstance(CIPHER_ALGORITHM);
            // cipher.init(javax.crypto.Cipher.ENCRYPT_MODE, secretKey, new javax.crypto.spec.IvParameterSpec(KEY_VI));
            cipher.init(javax.crypto.Cipher.ENCRYPT_MODE, secretKey, new javax.crypto.spec.IvParameterSpec(iv));*/
            // 根據密碼器的初始化方式加密
            byte[] byteAES = cipher.doFinal(content);

            // 將加密後的數據轉換爲字符串
            return byteAES;

        } catch (Exception e) {
            e.printStackTrace();

        }
        return null;

    }

    /**
     * AES解密
     */
    public static byte[] decode(byte[] key, byte[] iv, byte[] content) {
        try {
            javax.crypto.SecretKey secretKey = new SecretKeySpec(key, AES);
            Cipher cipher = Cipher.getInstance(De_CIPHER_ALGORITHM);
            cipher.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(iv));
            //cipher.init(javax.crypto.Cipher.DECRYPT_MODE, secretKey);
            // 解密
            byte[] byteDecode = cipher.doFinal(content);
            return byteDecode;
        } catch (Exception e) {
            e.printStackTrace();

        }
        return null;

    }

    public static byte[] HexString2Bytes(String hexstr) {
        byte[] b = new byte[hexstr.length() / 2];
        int j = 0;
        for (int i = 0; i < b.length; i++) {
            char c0 = hexstr.charAt(j++);
            char c1 = hexstr.charAt(j++);
            b[i] = (byte) ((parse(c0) << 4) | parse(c1));
        }
        return b;
    }

    private static int parse(char c) {
        if (c >= 'a')
            return (c - 'a' + 10) & 0x0f;
        if (c >= 'A')
            return (c - 'A' + 10) & 0x0f;
        return (c - '0') & 0x0f;
    }
}
